#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
搜索处理模块
负责执行搜索和处理搜索结果的选择
"""

import time
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException

class SearchHandler:
    """搜索处理类，处理搜索和结果选择相关操作"""
    
    def __init__(self, driver):
        """初始化搜索处理器
        
        Args:
            driver: WebDriver对象
        """
        self.driver = driver
        self.search_url = "https://www.hifini.com/search--1.htm"
        self.wait = WebDriverWait(self.driver, 10)
    
    def perform_search(self, search_text):
        """执行搜索操作
        
        Args:
            search_text: 搜索关键词
            
        Returns:
            list: 搜索结果列表，每个结果包含标题和URL，失败时返回空列表
        """
        # 打开搜索页面
        print(f"\n正在打开搜索页面: {self.search_url}")
        self.driver.get(self.search_url)
        
        try:
            # 等待页面加载完成
            time.sleep(1)
            
            # 查找搜索输入框
            search_input = self.wait.until(
                EC.presence_of_element_located((By.CLASS_NAME, "form-control"))
            )
            
            # 清空输入框并输入搜索内容
            search_input.clear()
            search_input.send_keys(search_text)
            print(f"已输入搜索内容: {search_text}")
            
            # 查找搜索按钮并点击
            submit_button = self.driver.find_element(By.ID, "submit")
            submit_button.click()
            print("已点击搜索按钮，等待结果加载...")
            
            # 等待搜索结果加载
            time.sleep(3)
            
            # 解析搜索结果
            return self._parse_search_results()
            
        except Exception as e:
            print(f"执行搜索时出错: {str(e)}")
            return []
    
    def _parse_search_results(self):
        """解析搜索结果
        
        Returns:
            list: 搜索结果列表，每个结果包含标题和URL
        """
        try:
            # 等待搜索结果列表加载
            threadlist = self.wait.until(
                EC.presence_of_element_located((By.CLASS_NAME, "threadlist"))
            )
            
            # 获取所有结果链接
            subject_links = threadlist.find_elements(By.CSS_SELECTOR, ".subject a")
            
            if not subject_links:
                print("未找到任何搜索结果")
                return []
            
            # 解析结果
            results = []
            for link in subject_links:
                title = link.text or "无标题链接"
                url = link.get_attribute("href")
                results.append({
                    "title": title,
                    "url": url
                })
            
            print(f"\n找到 {len(results)} 个搜索结果")
            return results
            
        except Exception as e:
            print(f"解析搜索结果时出错: {str(e)}")
            return []
    
    def select_results(self, results, auto_select=True, max_results=None):
        """让用户选择要处理的搜索结果
        
        Args:
            results: 搜索结果列表
            auto_select: 是否自动选择结果而不询问用户
            max_results: 指定要处理的结果数量，None表示由用户选择或使用默认值
            
        Returns:
            list: 用户选择的结果列表
        """
        if not results:
            return []
        
        max_links = min(len(results), 20)  # 最多显示20个结果
        
        # 显示搜索结果
        print("\n搜索结果:")
        for i in range(max_links):
            print(f"{i+1}. {results[i]['title']}")
        
        # 自动模式下，根据max_results参数自动选择结果
        if auto_select:
            # 如果未指定数量，默认最多处理10个结果
            if max_results is None:
                max_to_process = min(len(results), 10)
            else:
                max_to_process = min(len(results), max_results)
            
            # 显示将要处理的链接
            print(f"\n将要自动处理以下 {max_to_process} 个链接:")
            selected_results = []
            for i in range(max_to_process):
                print(f"{i+1}. {results[i]['title']}")
                selected_results.append(results[i])
            
            return selected_results
        
        # 以下是手动模式的代码
        # 如果指定了max_results，直接将其作为显示的链接数
        if max_results is not None:
            display_links = min(max_results, max_links)
            print(f"\n将显示前 {display_links} 个搜索结果")
        else:
            # 询问用户要显示前几个结果
            print(f"\n请选择要显示的链接数量 (1-{max_links})，直接回车显示全部: ")
            user_input = input().strip()
            
            if not user_input:
                display_links = max_links
                print(f"将显示全部 {display_links} 个链接")
            else:
                try:
                    display_links = int(user_input)
                    if display_links < 1 or display_links > max_links:
                        print(f"输入无效，默认显示10个链接")
                        display_links = min(10, max_links)
                except ValueError:
                    print("输入无效，默认显示10个链接")
                    display_links = min(10, max_links)
        
        # 显示选择的链接
        print("\n请选择要处理的链接:")
        for i in range(display_links):
            print(f"{i+1}. {results[i]['title']}")
            
        # 让用户选择要处理的链接
        print("\n请输入要处理的链接编号 (多个编号用逗号分隔，例如1,3,5；范围使用连字符，例如1-5):")
        print("直接回车将处理全部显示的链接:")
        selected_input = input().strip()
        
        # 如果用户直接回车，选择所有显示的链接
        if not selected_input:
            selected_indices = list(range(display_links))
            print(f"已选择处理全部 {display_links} 个链接")
        else:
            selected_indices = self._parse_selection_input(selected_input, display_links)
        
        if not selected_indices:
            print("未选择有效的链接编号，默认处理第一个链接")
            selected_indices = [0]
        
        # 显示将要处理的链接
        print("\n将要处理以下链接:")
        selected_results = []
        for i, index in enumerate(selected_indices):
            print(f"{i+1}. {results[index]['title']}")
            selected_results.append(results[index])
        
        # 确认处理
        print("\n是否确认处理这些链接? (y/n): ")
        confirm = input().lower() == 'y'
        if not confirm:
            print("已取消处理")
            return []
        
        return selected_results
    
    def _parse_selection_input(self, input_text, max_value):
        """解析用户输入的选择
        
        Args:
            input_text: 用户输入的选择文本
            max_value: 最大有效索引值
            
        Returns:
            list: 解析后的索引列表（0-based）
        """
        if not input_text:
            return []
            
        try:
            # 解析用户输入的编号
            selected_indices = []
            for part in input_text.split(','):
                part = part.strip()  # 移除空格
                if '-' in part:  # 处理范围，例如 1-5
                    try:
                        range_parts = part.split('-')
                        if len(range_parts) == 2:
                            start, end = map(int, range_parts)
                            
                            # 确保开始和结束值都在有效范围内
                            if 1 <= start <= max_value and 1 <= end <= max_value:
                                # 处理不同方向的范围
                                min_val = min(start, end)
                                max_val = max(start, end)
                                
                                # Python索引从0开始，所以减1
                                for i in range(min_val - 1, max_val):
                                    selected_indices.append(i)
                                
                                print(f"已添加范围 {min_val} 到 {max_val} 的链接")
                            else:
                                print(f"忽略范围外编号: {part} (有效范围: 1-{max_value})")
                        else:
                            print(f"忽略无效范围格式: {part} (正确格式如: 2-5)")
                    except ValueError:
                        print(f"忽略无效范围格式: {part} (应为数字-数字)")
                else:  # 单个数字
                    try:
                        index = int(part) - 1
                        if 0 <= index < max_value:
                            selected_indices.append(index)
                            print(f"已添加编号 {part} 的链接")
                        else:
                            print(f"忽略范围外编号: {part} (有效范围: 1-{max_value})")
                    except ValueError:
                        print(f"忽略无效编号: {part}")
            
            # 去重并排序
            return sorted(set(selected_indices))
            
        except Exception as e:
            print(f"解析输入时出错: {str(e)}")
            return []
    
    def search_and_select(self, search_term, auto_select=False):
        """执行搜索并让用户选择一个结果
        
        Args:
            search_term: 搜索关键词
            auto_select: 是否自动选择第一个搜索结果，不询问用户
            
        Returns:
            str: 选中的搜索结果URL，如果没有选择则返回None
        """
        if not search_term:
            print("错误：搜索关键词为空")
            return None
        
        try:
            print(f"\n正在搜索: {search_term}")
            # 导航到搜索页面
            search_url = "https://www.hifini.com/search-{}.htm".format(search_term)
            self.driver.get(search_url)
            time.sleep(2)
            
            # 找到所有搜索结果链接
            search_results = self.driver.find_elements(By.CSS_SELECTOR, ".subject a")
            
            if not search_results:
                print("未找到任何搜索结果")
                return None
            
            print(f"\n找到 {len(search_results)} 个搜索结果:")
            
            # 显示搜索结果供选择
            results_list = []
            for i, result in enumerate(search_results, 1):
                title = result.text
                url = result.get_attribute("href")
                results_list.append((title, url))
                print(f"{i}. {title}")
            
            # 自动选择第一个结果
            if auto_select and results_list:
                selected_title, selected_url = results_list[0]
                print(f"\n自动选择第一个结果: {selected_title}")
                return selected_url
            
            # 让用户选择一个结果
            print("\n请输入要查看的结果编号，或按Enter键跳过: ")
            choice = input().strip()
            
            if choice and choice.isdigit():
                choice_idx = int(choice)
                if 1 <= choice_idx <= len(results_list):
                    selected_title, selected_url = results_list[choice_idx - 1]
                    print(f"已选择: {selected_title}")
                    return selected_url
                else:
                    print("无效的选择编号")
            
            print("未选择任何结果")
            return None
            
        except Exception as e:
            print(f"搜索过程中出错: {str(e)}")
            return None 